#ifndef _HY_JSON_READER_H_
#define _HY_JSON_READER_H_

#include <json/json.h>
#include <map>

class hy_json_reader
{
public:
	hy_json_reader(){}
	~hy_json_reader(){}

	int load_json_string(const std::string& doc, Json::Value& con)
	{
		if (_reader.parse(doc, con) == false)
		{
			hy_log(ll_error, ("Failed to parse file %s\n error: %s\n context: %s.\n"), doc
				, _reader.getFormattedErrorMessages().c_str(), doc.data());

			return hy_error;
		}
		return hy_right;
	}

	//*************************************************************************
	// Method:    hy_json_reader::load_json_config
	// Returns:   int
	// Parameter: const char * doc
	// Parameter: Json::Value & con
	// Qualifier:
	//*************************************************************************
	int load_json_config(const char* doc, Json::Value& con)
	{
		{
			FILE* file = fopen(doc, "rb");
			if (file == 0)
			{
				hy_log(ll_error, (" Failed to open file %s.\n"), doc);
				return hy_error;
			}

			fseek(file, 0, SEEK_END);
			long size = ftell(file);
			fseek(file, 0, SEEK_SET);

			char* buffer = new char[size + 1];
			memset(buffer,0,size + 1);

			if (fread(buffer, 1, size, file) == (unsigned long) size)
			{
				if (_reader.parse(buffer,buffer+size, con) == false)
				{
					hy_log(ll_error, ("Failed to parse file %s\n error: %s\n context: %s.\n"), doc
						, _reader.getFormattedErrorMessages().c_str(), buffer);

					return hy_error;
				}
			}

			fclose(file);
			delete[] buffer;

			
		}
		return hy_right;
	}

protected:
	Json::Reader	_reader;
};

struct hy_basic_config
{
	typedef std::map<hy_i32_t, Json::Value* > jsons_t;

	//*************************************************************************
	// Method:    hy_basic_config::hy_basic_config
	// Returns:   
	// Parameter: hy_json_reader * reader
	// Parameter: const char * doc
	// Qualifier:
	//*************************************************************************
	hy_basic_config(hy_json_reader* reader,const char* doc)
	{
		if (reader->load_json_config(doc,_json) == hy_right)
		{
			covert_json_to_map();
		}
	}

	//*************************************************************************
	// Method:    hy_basic_config::json
	// Returns:   Json::Value&
	// Parameter: void
	// Qualifier:
	//*************************************************************************
	Json::Value& json(void)
	{
		return _json;
	}

	//*************************************************************************
	// Method:    hy_basic_config::map
	// Returns:   jsons_t&
	// Parameter: void
	// Qualifier:
	//*************************************************************************
	jsons_t& map(void)
	{
		return _map;
	}

	void update_version(void);
	void revert_version(void);

	//*************************************************************************
	// Method:    hy_basic_config::covert_json_to_map
	// Returns:   void
	// Parameter: void
	// Qualifier:
	//*************************************************************************
	void covert_json_to_map(void)
	{
		for (Json::Value::iterator iter = this->json().begin(); 
			iter != this->json().end(); iter++)
		{
			Json::Value& json = *iter;
			_map[atoi(iter.key().asCString())] = &json;
		}
	}
private:
	Json::Value _json;
	jsons_t		_map;
	int _version;
};
#endif  //_HY_JSON_READER_H_
